package cn.com.blueInfo.core.config;

import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 对所有RestController 增加/api前缀，
 * 对所有Controller 增加/page前缀，
 * 这也是规范后续的所有开发工作。
 */
//@Configuration
public class ControllerPathConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册自定义拦截器，拦截所有请求（排除已在拦截器内部处理）
        registry.addInterceptor(new PathPrefixInterceptor())
                .addPathPatterns("/**"); // 拦截所有路径，内部会排除Knife4j相关路径
    }

    public static class PathPrefixInterceptor implements HandlerInterceptor {

        // Knife4j相关路径（需要排除，避免被添加前缀）
        private static final String[] KNIFE4J_PATHS = {
                "/swagger-ui.html", "/swagger-ui/", "/v3/api-docs",
                "/webjars/", "/doc.html", "/favicon.ico"
        };

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 1. 排除Knife4j相关路径，直接放行
            String originalUri = request.getRequestURI();
            for (String knife4jPath : KNIFE4J_PATHS) {
                if (originalUri.startsWith(knife4jPath)) {
                    return true;
                }
            }

            // 2. 仅处理控制器方法（HandlerMethod）
            if (!(handler instanceof HandlerMethod)) {
                return true;
            }
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Class<?> controllerClass = handlerMethod.getBeanType();

            // 3. 判断是否需要添加前缀（仅处理指定包下的控制器）
            Package controllerPackage = controllerClass.getPackage();
            if (controllerPackage == null || !controllerPackage.getName().startsWith("cn.com.blueInfo")) {
                return true;
            }

            // 4. 根据注解类型确定前缀
            String prefix = "";
            if (AnnotationUtils.findAnnotation(controllerClass, RestController.class) != null) {
                prefix = "/api";
            } else if (AnnotationUtils.findAnnotation(controllerClass, Controller.class) != null) {
                prefix = "/page";
            }

            // 5. 包装请求（添加前缀）
            if (!prefix.isEmpty()) {
                request = new PrefixRequestWrapper(request, prefix);
                // 将包装后的请求存入属性，供后续流程使用（Spring MVC内部会使用此请求）
                request.setAttribute("WRAPPED_REQUEST", request);
            }

            return true;
        }
    }

    public static class PrefixRequestWrapper extends HttpServletRequestWrapper {
        private final String newUri;

        public PrefixRequestWrapper(HttpServletRequest request, String prefix) {
            super(request);
            // 原始路径（如"/user/list"）
            String originalUri = request.getRequestURI();
            // 拼接前缀（如"/api/user/list"）
            this.newUri = prefix + originalUri;
        }

        @Override
        public String getRequestURI() {
            return newUri;
        }

        @Override
        public String getServletPath() {
            return newUri;
        }

    }
}
